#include "SoundDuplex.h"

using namespace ipsound;

void InitWaveFormat( WAVEFORMATEX& wfx, const unsigned short& channelsNum,
			   const unsigned long& samplesPerSec, const unsigned short& bitsPerSample )
{
	memset( &wfx, 0, sizeof(WAVEFORMATEX) );
	wfx.wFormatTag = WAVE_FORMAT_PCM;
	wfx.nChannels = channelsNum;
	wfx.nSamplesPerSec = samplesPerSec;
	wfx.wBitsPerSample = bitsPerSample;
	wfx.nBlockAlign = (wfx.wBitsPerSample * wfx.nChannels) / 8;
	wfx.nAvgBytesPerSec = samplesPerSec * wfx.nBlockAlign;
}

SoundDuplex::SoundDuplex( MutexBuffer* readBuf, MutexBuffer* writeBuf, HWND window )
:readBuf( readBuf )
,writeBuf( writeBuf )
,channelsNum( 1 )
,samplesPerSec( 8000 )
,bitsPerSample( 16 )
,soundPlay( 0 )
,playBufSec( 2 )
,captureBufSec( 2 )
,notifySamplesNum( 4 )
{
	WAVEFORMATEX wfx = {0};
	InitWaveFormat( wfx, channelsNum, samplesPerSec, bitsPerSample );

	/*DSCEFFECTDESC captureEffects[2];
	captureEffects[0].dwSize = sizeof(DSCEFFECTDESC);
	captureEffects[0].dwReserved1 = captureEffects[0].dwReserved2 = 0;
	captureEffects[0].dwFlags = DSCFX_LOCSOFTWARE;
	captureEffects[0].guidDSCFXClass = GUID_DSCFX_CLASS_AEC;
	captureEffects[0].guidDSCFXInstance = GUID_DSCFX_MS_AEC;

	captureEffects[1].dwSize = sizeof(DSCEFFECTDESC);
	captureEffects[1].dwReserved1 = captureEffects[1].dwReserved2 = 0;
	captureEffects[1].dwFlags = DSCFX_LOCSOFTWARE;
	captureEffects[1].guidDSCFXClass = GUID_DSCFX_CLASS_NS;
	captureEffects[1].guidDSCFXInstance = GUID_DSCFX_MS_NS;*/


	DSCBUFFERDESC captureBufDesc = {0};
	captureBufDesc.dwSize = sizeof(DSCBUFFERDESC);
	captureBufDesc.dwFlags = 0/*DSCBCAPS_CTRLFX*/;
	captureBufDesc.dwReserved = 0;
	captureBufDesc.dwFXCount = 0/*2*/;
	captureBufDesc.dwBufferBytes = captureBufSec * wfx.nAvgBytesPerSec;
	captureBufDesc.lpwfxFormat = &wfx;
	captureBufDesc.lpDSCFXDesc = 0/*captureEffects*/;

	DSBUFFERDESC playBufDesc = {0};
	playBufDesc.dwSize = sizeof(DSBUFFERDESC);
	playBufDesc.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_LOCSOFTWARE;
	playBufDesc.dwBufferBytes = playBufSec * wfx.nAvgBytesPerSec;
	playBufDesc.lpwfxFormat = &wfx;

	HRESULT hr = DirectSoundFullDuplexCreate8( 0, 0, &captureBufDesc, &playBufDesc, window, DSSCL_PRIORITY, &duplex8, &captureBuf8, &playBuf8, 0 );

	soundPlay = new SoundPlay( readBuf, playBuf8 );
	soundPlay->SetNotifySamplesNum( notifySamplesNum );

	soundCapture = new SoundCapture( writeBuf, captureBuf8 );
	soundCapture->SetNotifySamplesNum( notifySamplesNum );
}

size_t SoundDuplex::GetMinimumPlaySize()
{
	return playBufSec * samplesPerSec * (bitsPerSample / 8) / notifySamplesNum;
}

void SoundDuplex::StartCapture()
{
	soundCapture->Start();
}

void SoundDuplex::StartPlay()
{
	soundPlay->Start();
}

SoundDuplex::~SoundDuplex()
{
	delete soundPlay;
	captureBuf8->Release();
	playBuf8->Release();
	duplex8->Release();
}
